﻿using System.Collections.Generic;
using UnityEngine;

namespace Core.Res
{
    public partial class BundleLoader
    {
        public class Asset : LoadAwaiter, IAsset
        {
            private readonly BundleLoader loader;
            private AssetBundleRequest mRequest;

            private string abName;

            public UnityEngine.Object Obj { get; private set; }

            public RefCnt Ref { get; }
            public Stack<GameObject> Pool { get; set; }

            public Asset(BundleLoader loader) : base(loader)
            {
                this.loader = loader;

                Pool = new Stack<GameObject>();

                Ref = new RefCnt();
            }

            public void SetInfo(string asset_name)
            {
                var assetInfo = loader.ResDict.GetAsset(asset_name);
                abName = assetInfo.Bundle;
                //Name = asset_name;
                //ABName = bundle_name;
            }

            public override void Start()
            {
                if (loader.assets.ContainsKey(Name) || Name.EndsWith(".unity"))
                {
                    State = ELoadState.Complete;
                    return;
                }

                if (loader.bundles.ContainsKey(abName) == false)
                {
                    if (Debug.unityLogger.logEnabled)
                    {
                        Debug.LogError("加载的资源不存在" + abName);
                    }

                    State = ELoadState.Complete;
                    return;
                }

                State = ELoadState.Loading;
                Progress = 0;

                var bundle = loader.bundles[abName];
                if (bundle.Ab == null)
                {
                    if (Debug.unityLogger.logEnabled)
                    {
                        Debug.LogError(
                            $"Time={Time.realtimeSinceStartup}  【Asset】 Error; Bundle is Null; name = {Name}");
                    }

                    State = ELoadState.Complete;
                    return;
                }

                //Debug.Log($"Time={Time.realtimeSinceStartup}  【Asset】; AssetName = {AssetName}");

                mRequest = bundle.Ab.LoadAssetAsync(Name);
            }

            public override void Update()
            {
                if (State != ELoadState.Loading || mRequest == null) return;

                Progress = mRequest.progress;

                if (mRequest.isDone)
                {
                    Obj = mRequest.asset;
                    Progress = 1f;
                    State = ELoadState.Complete;
                    loader.assets[Name] = this;
                }
            }

            public override void Finish()
            {
                Awaiter?.SetResult();
                Awaiter = null;
            }

            public void Dispose()
            {
                State = ELoadState.Invalid;

                Obj = null;
            }

            public void LoadSync()
            {
                var bundle = loader.bundles[abName];

                Obj = bundle.Ab.LoadAsset(Name);

                loader.assets[Name] = this;
                loader.missing.Remove(Name);
            }
        }
    }
}
